import { defineStore } from "pinia";
import { getToken, removeToken, setToken } from "@/utils/token-utils";
import type { UserInfoState } from "./interface";
import { reqGetUserInfo, reqLogin, reqLogout } from "@/api/user";
import { allAsyncRoutes, anyRoutes, staticRoutes } from "@/router/routes";
import type { RouteRecordRaw } from "vue-router";
import router from "@/router";
import { cloneDeep } from "lodash";

// 封装一个函数，用于递归过滤出用户拥有的路由
// 动态路由
function generateRoutes(allAsyncRoutes: RouteRecordRaw[], routeNames: string[]) {
    return allAsyncRoutes.filter(route => {
        // 将路由中name属性与routeNames中的字符串进行比较，如果相同，则返回true
        if (routeNames.indexOf(route.name as string) === -1) {
            return false;
        }
        // 如果有子路由，则递归调用
        if (route.children && route.children.length > 0) {
            route.children = generateRoutes(route.children, routeNames);
        }
        return true;
    });
}

// 任意路由
function addRoutes(routes: RouteRecordRaw[]) {
    routes.forEach(route => {
        router.addRoute(route);
    });
}

// 重置路由
function resetRoutes(staticRoutes: RouteRecordRaw[]) {
    // 先删除所有路由
    router.getRoutes().forEach(route => {
        if (route.name !== "Login") {
            router.removeRoute(route.name as string);
        }
    });
    // 再添加静态路由
    addRoutes(staticRoutes);
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore("userInfo", {
    state: (): UserInfoState => ({
        token: getToken() as string,
        userInfo: {
            routes: [],
            buttons: [],
            roles: [],
            name: "",
            avatar: "",
        },
        menuRoutes: staticRoutes,
    }),

    actions: {
        // 重写登录逻辑
        async login(username: string, password: string) {
            try {
                const res = await reqLogin({ username, password });
                setToken(res.token); // 设置token本地存储
                this.token = res.token; // 设置token状态,保存到state
            } catch (e) {
                return Promise.reject(e); // 抛出异常
            }
        },

        // 重写获取用户信息逻辑
        async getInfo() {
            try {
                this.userInfo = await reqGetUserInfo();
                // 生成动态路由
                const asyncRoutes = generateRoutes(cloneDeep(allAsyncRoutes), this.userInfo.routes);
                // 生成最终的路由
                this.menuRoutes = [...staticRoutes, ...asyncRoutes, anyRoutes];
                // 添加路由
                addRoutes([...asyncRoutes, anyRoutes]);
            } catch (e) {
                return Promise.reject(e); // 抛出异常
            }
        },
        // 退出登录逻辑
        async logout() {
            try {
                await reqLogout();
                // 重置路由器
                resetRoutes(staticRoutes);
                this.reset(); // 重置状态
            } catch (e) {
                return Promise.reject(e); // 抛出异常
            }
        },
        // 重置状态
        reset() {
            // 删除local中保存的token
            removeToken();
            // 提交重置用户信息的mutation
            this.token = "";
            this.userInfo = {
                routes: [],
                buttons: [],
                roles: [],
                name: "",
                avatar: "",
            };
        },
    },
});
